#ifndef PRECISIONIDENTIFY_H
#define PRECISIONIDENTIFY_H

#include "opencv2/core/mat.hpp"
#include <QObject>

class PrecisionIdentify : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool identifiThresholdAuto READ identifiThresholdAuto WRITE setidentifiThresholdAuto NOTIFY identifiThresholdAutoChanged)
    Q_PROPERTY(int identifiThreshold READ identifiThreshold WRITE setidentifiThreshold NOTIFY identifiThresholdhanged)
    Q_PROPERTY(float markEnhancement READ markEnhancement WRITE setmarkEnhancement NOTIFY markEnhancementchanged)
    Q_PROPERTY(float markSmoothing READ markSmoothing WRITE setmarkSmoothing NOTIFY markSmoothingdhanged)
    //0自动 1反向 2正常
    Q_PROPERTY(int overturn READ overturn WRITE setoverturn NOTIFY overturnchanged)

public:
    static PrecisionIdentify &getInstance();

    enum Matching{
        Template,
        Binarization,
        gradient
    };

    bool handleIdentify(const cv::Mat &frameGray,cv::Rect &rect,bool display=false);

    void binarizeImage(const cv::Mat& grayImage, cv::Mat& binaryImage);
    void binarizeImage(const cv::Mat& grayImage, cv::Mat& binaryImage , cv::Mat &displayImage);
    void setMethon(Matching method);

    bool identifiThresholdAuto() const {return identifiThresholdAuto_;};
    void setidentifiThresholdAuto(bool identifiThresholdAuto);

    int identifiThreshold() const {return identifiThreshold_;};
    void setidentifiThreshold(int identifiThreshold);

    float overturn() const {return overturn_;};
    void setoverturn (float overturn );

    int markEnhancement() const {return markEnhancement_;};
    void setmarkEnhancement(int markEnhancement);
    int markSmoothing() const {return markSmoothing_;};
    void setmarkSmoothing(int markSmoothing);
    Q_INVOKABLE void testBinaryIdentifyImg();
    bool handleIdentifyV2(const cv::Mat &frameGray, cv::Mat &searchImage, cv::Rect2d &roi, float scale);
signals:
    void identifiThresholdAutoChanged();
    void identifiThresholdhanged();
    void markEnhancementchanged();
    void markSmoothingdhanged();
    void overturnchanged();

public slots:
    void valueTableLoad();

private:
    bool identifiThresholdAuto_;
    int identifiThreshold_;
    float markEnhancement_;
    float markSmoothing_;
    int overturn_;

    cv::Mat identifiGrayTemp;
    PrecisionIdentify(QObject *parent = nullptr);
    ~PrecisionIdentify();
    bool needsInversion(cv::Mat &binaryImage);
    PrecisionIdentify(const PrecisionIdentify &) = delete;
    PrecisionIdentify &operator=(const PrecisionIdentify &) = delete;
    Matching method_;
    int findBackgroundColor(const cv::Mat &binaryImage);
    cv::Rect findMinBoundingRect(const cv::Mat &binaryImage);

};

#endif // PRECISIONIDENTIFY_H
